#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
HTTP API测试脚本
用于测试WebSocket代理桥接服务的HTTP接口
"""

import asyncio
import aiohttp
import json
import logging
import argparse
from datetime import datetime

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class HTTPAPITester:
    """HTTP API测试器"""
    
    def __init__(self, api_base_url: str):
        """
        初始化HTTP API测试器
        
        Args:
            api_base_url: API基础URL，如 http://127.0.0.1:8998
        """
        self.api_base_url = api_base_url.rstrip('/')
        self.session = None
    
    async def __aenter__(self):
        """异步上下文管理器入口"""
        self.session = aiohttp.ClientSession()
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """异步上下文管理器出口"""
        if self.session:
            await self.session.close()
    
    async def test_health_check(self):
        """测试健康检查端点"""
        logger.info("测试健康检查端点...")
        
        try:
            async with self.session.get(f"{self.api_base_url}/health") as response:
                if response.status == 200:
                    data = await response.json()
                    logger.info(f"✓ 健康检查成功: {json.dumps(data, indent=2, ensure_ascii=False)}")
                    return True
                else:
                    logger.error(f"✗ 健康检查失败: HTTP {response.status}")
                    return False
                    
        except Exception as e:
            logger.error(f"✗ 健康检查异常: {str(e)}")
            return False
    
    async def test_get_connections(self):
        """测试获取连接列表端点"""
        logger.info("测试获取连接列表...")
        
        try:
            async with self.session.get(f"{self.api_base_url}/connections") as response:
                if response.status == 200:
                    data = await response.json()
                    logger.info(f"✓ 获取连接列表成功:")
                    logger.info(f"  连接数量: {data.get('count', 0)}")
                    
                    connections = data.get('connections', [])
                    for i, conn in enumerate(connections):
                        logger.info(f"  连接 {i+1}:")
                        logger.info(f"    ID: {conn.get('connection_id')}")
                        logger.info(f"    客户端: {conn.get('client_address')}")
                        logger.info(f"    服务端: {conn.get('server_address')}")
                        logger.info(f"    创建时间: {conn.get('created_at')}")
                    
                    return connections
                else:
                    logger.error(f"✗ 获取连接列表失败: HTTP {response.status}")
                    return []
                    
        except Exception as e:
            logger.error(f"✗ 获取连接列表异常: {str(e)}")
            return []
    
    async def test_send_message(self, connection_id: str, message: str, message_type: str = "text"):
        """
        测试发送消息端点
        
        Args:
            connection_id: 目标连接ID
            message: 要发送的消息
            message_type: 消息类型
        """
        logger.info(f"测试发送消息到连接 {connection_id}...")
        
        payload = {
            "connection_id": connection_id,
            "message": message,
            "message_type": message_type
        }
        
        try:
            async with self.session.post(
                f"{self.api_base_url}/send",
                json=payload,
                headers={'Content-Type': 'application/json'}
            ) as response:
                
                response_data = await response.json()
                
                if response.status == 200:
                    logger.info(f"✓ 消息发送成功: {response_data.get('message')}")
                    return True
                elif response.status == 404:
                    logger.warning(f"✗ 连接不存在: {response_data.get('error')}")
                    return False
                elif response.status == 400:
                    logger.error(f"✗ 请求参数错误: {response_data.get('error')}")
                    logger.error(f"  详细信息: {response_data.get('details')}")
                    return False
                else:
                    logger.error(f"✗ 发送消息失败: HTTP {response.status}")
                    logger.error(f"  响应: {response_data}")
                    return False
                    
        except Exception as e:
            logger.error(f"✗ 发送消息异常: {str(e)}")
            return False
    
    async def test_disconnect_connection(self, connection_id: str):
        """
        测试断开连接端点
        
        Args:
            connection_id: 要断开的连接ID
        """
        logger.info(f"测试断开连接 {connection_id}...")
        
        try:
            async with self.session.delete(
                f"{self.api_base_url}/connections/{connection_id}"
            ) as response:
                
                response_data = await response.json()
                
                if response.status == 200:
                    logger.info(f"✓ 连接断开成功: {response_data.get('message')}")
                    return True
                elif response.status == 404:
                    logger.warning(f"✗ 连接不存在: {response_data.get('error')}")
                    return False
                else:
                    logger.error(f"✗ 断开连接失败: HTTP {response.status}")
                    logger.error(f"  响应: {response_data}")
                    return False
                    
        except Exception as e:
            logger.error(f"✗ 断开连接异常: {str(e)}")
            return False
    
    async def test_invalid_requests(self):
        """测试无效请求的处理"""
        logger.info("测试无效请求处理...")
        
        # 测试无效的发送消息请求
        invalid_payloads = [
            {},  # 空请求
            {"connection_id": ""},  # 空连接ID
            {"connection_id": "test", "message": ""},  # 空消息
            {"connection_id": "test", "message": "hello", "message_type": "invalid"},  # 无效消息类型
        ]
        
        for i, payload in enumerate(invalid_payloads):
            logger.info(f"  测试无效请求 {i+1}: {payload}")
            
            try:
                async with self.session.post(
                    f"{self.api_base_url}/send",
                    json=payload,
                    headers={'Content-Type': 'application/json'}
                ) as response:
                    
                    if response.status == 400:
                        response_data = await response.json()
                        logger.info(f"    ✓ 正确返回400错误: {response_data.get('error')}")
                    else:
                        logger.warning(f"    ✗ 未返回预期的400错误: HTTP {response.status}")
                        
            except Exception as e:
                logger.error(f"    ✗ 测试无效请求异常: {str(e)}")
    
    async def run_comprehensive_test(self):
        """运行综合测试"""
        logger.info("=" * 60)
        logger.info("开始HTTP API综合测试")
        logger.info("=" * 60)
        
        # 1. 健康检查
        health_ok = await self.test_health_check()
        if not health_ok:
            logger.error("健康检查失败，停止测试")
            return
        
        logger.info("-" * 40)
        
        # 2. 获取连接列表
        connections = await self.test_get_connections()
        
        logger.info("-" * 40)
        
        # 3. 测试发送消息（如果有连接）
        if connections:
            connection_id = connections[0]['connection_id']
            
            # 发送文本消息
            test_message = json.dumps({
                "type": "api_test",
                "message": "这是来自HTTP API的测试消息",
                "timestamp": datetime.now().isoformat()
            }, ensure_ascii=False)
            
            await self.test_send_message(connection_id, test_message, "text")
            
            # 等待一下
            await asyncio.sleep(1)
            
            # 发送另一条消息
            await self.test_send_message(
                connection_id, 
                "Hello from HTTP API!", 
                "text"
            )
            
        else:
            logger.info("没有活跃连接，跳过消息发送测试")
        
        logger.info("-" * 40)
        
        # 4. 测试无效请求
        await self.test_invalid_requests()
        
        logger.info("-" * 40)
        
        # 5. 测试不存在的连接
        await self.test_send_message("non-existent-id", "test message")
        
        logger.info("=" * 60)
        logger.info("HTTP API测试完成")
        logger.info("=" * 60)


async def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='HTTP API测试工具')
    parser.add_argument('--api-url', default='http://127.0.0.1:8998',
                       help='API基础URL (默认: http://127.0.0.1:8998)')
    parser.add_argument('--test-type', choices=['health', 'connections', 'send', 'comprehensive'],
                       default='comprehensive', help='测试类型')
    parser.add_argument('--connection-id', help='指定连接ID（用于发送消息测试）')
    parser.add_argument('--message', default='Hello from API test!', 
                       help='要发送的测试消息')
    
    args = parser.parse_args()
    
    async with HTTPAPITester(args.api_url) as tester:
        if args.test_type == 'health':
            await tester.test_health_check()
        elif args.test_type == 'connections':
            await tester.test_get_connections()
        elif args.test_type == 'send':
            if args.connection_id:
                await tester.test_send_message(args.connection_id, args.message)
            else:
                logger.error("发送消息测试需要指定 --connection-id")
        else:  # comprehensive
            await tester.run_comprehensive_test()


if __name__ == "__main__":
    asyncio.run(main())